package com.hcb.micro.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

public class CommonUtil {
	public static Logger log = Logger.getLogger(CommonUtil.class);

	/**
	 * 平台签名密钥
	 */
	public static final String SIGN_KEY = "yangegegegeyan";

	private static Map<String, String> bankType = new HashMap<String, String>();

	static {
		bankType.put("1", "工商银行");
		bankType.put("2", "农业银行");
		bankType.put("3", "中国银行");
		bankType.put("4", "建设银行");
		bankType.put("5", "邮政储蓄");
		bankType.put("6", "交通银行");
		bankType.put("7", "招商银行");
		bankType.put("8", "光大银行");
		bankType.put("9", "中信银行");
	}

	/**
	 * 将BASE64字符串恢复为二进制数据
	 * 
	 * @param base64String
	 * @return
	 */
	public static byte[] getBytesFromBASE64(String base64String) {
		try {
			return Base64.decodeBase64(base64String.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			return null;
		}
	}

	public static String getBASE64FromBytes(byte[] base64String) {
		try {
			return new String(Base64.encodeBase64(base64String));
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 将输入流转为字节数组格式的对象
	 * 
	 * @param in
	 *            输入流对象
	 * @return
	 */
	public static byte[] convertInputStream2Bytes(InputStream in) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int length = 0;
		byte[] buffer = new byte[1024];

		try {
			while ((length = in.read(buffer)) != -1) {
				out.write(buffer, 0, length);
			}

			return out.toByteArray();
		} catch (IOException e) {
			log.error("read from inputstream error.", e);
		} finally {
			try {
				out.close();
			} catch (IOException e) {
				log.error("close the outputstream error.", e);
			}
		}

		return null;
	}

	/**
	 * 将输入流转为字符串格式的对象
	 * 
	 * @param in
	 *            输入流对象
	 * @return
	 */
	public static String convertInputStream2Str(InputStream in) {
		String result = null;

		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int length = 0;
		byte[] buffer = new byte[1024];

		try {
			while ((length = in.read(buffer)) != -1) {
				out.write(buffer, 0, length);
			}

			result = new String(out.toByteArray());
		} catch (IOException e) {
			log.error("read from inputstream error.", e);
		} finally {
			try {
				out.close();
			} catch (IOException e) {
				log.error("close the outputstream error.", e);
			}
		}

		return result;
	}

	/**
	 * 发送短信
	 *
	 * @param str
	 * @return 验证通过返回true
	 */
	public static void sendSMS(String[] mobiles, String smsContent, int smsPriority) throws Exception {
		// int i;
		// try
		// {
		// i = SingletonClient.getClient().sendSMS(mobiles, smsContent, "",
		// smsPriority);
		// if (i != 0)
		// {
		// throw new Exception("发送短信失败！mobiles：" + mobiles + ",smsContent:" +
		// smsContent + ",i:" + i);
		// }
		// }
		// catch (RemoteException e)
		// {
		// log.warn("发送短信失败！mobiles：" + mobiles + ",smsContent:" + smsContent);
		// throw new Exception(e);
		// }
	}

	/**
	 * 生成指定长度的随机数字
	 *
	 * @param 随机数字长度
	 * @return 验证通过返回true
	 */
	public static String GenerateRandomCode(int length) {
		String result = "";
		for (int i = 0; i < length; i++) {
			result += nextInt(0, 9);
		}
		return result;
	}

	/**
	 * 生成一个唯一的UUID
	 *
	 * @return
	 */
	public static String generateUUID() {
		return UUID.randomUUID().toString().replace("-", "").toUpperCase().substring(0, 30);
	}

	private static int nextInt(final int min, final int max) {
		Random rand = new Random();
		int tmp = Math.abs(rand.nextInt());
		return tmp % (max - min + 1) + min;
	}

	/**
	 * 手机号验证
	 *
	 * @param str
	 * @return 验证通过返回true
	 */
	public static boolean isMobile(String str) {
		Pattern p = null;
		Matcher m = null;
		boolean b = false;
		p = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$"); // 验证手机号
		m = p.matcher(str);
		b = m.matches();
		return b;
	}

	/**
	 * 电话号码验证
	 *
	 * @param str
	 * @return 验证通过返回true
	 */
	public static boolean isPhone(String str) {
		Pattern p1 = null, p2 = null;
		Matcher m = null;
		boolean b = false;
		p1 = Pattern.compile("^[0][1-9]{2,3}-[0-9]{5,10}$"); // 验证带区号的
		p2 = Pattern.compile("^[1-9]{1}[0-9]{5,8}$"); // 验证没有区号的
		if (str.length() > 9) {
			m = p1.matcher(str);
			b = m.matches();
		} else {
			m = p2.matcher(str);
			b = m.matches();
		}
		return b;
	}

	/**
	 * 判断字符串是否为空
	 *
	 * @param str
	 * @return
	 */
	public static boolean isBlank(String str) {
		if (str == null || str.equals("")) {
			return true;
		}
		return false;
	}

	/**
	 * 把字符串转换成md5
	 *
	 * @param str
	 * @return
	 */
	public static String strToMD5(String str) throws UnsupportedEncodingException {

		try {
			byte[] input;
			input = str.getBytes(CommonConstant.CHARACTER_ENCODING);
			return bytesToHex(bytesToMD5(input));
		} catch (UnsupportedEncodingException e) {
			log.error("strToMD5编码不支持!", e);
			throw e;
		}
	}

	/**
	 * 把字节数组转成16进位制数
	 *
	 * @param bytes
	 * @return
	 */
	public static String bytesToHex(byte[] bytes) {
		StringBuffer md5str = new StringBuffer();
		// 把数组每一字节换成16进制连成md5字符串
		int digital;
		for (int i = 4; i < bytes.length - 4; i++) {
			digital = bytes[i];
			if (digital < 0) {
				digital += 256;
			}
			if (digital < 16) {
				md5str.append("0");
			}
			md5str.append(Integer.toHexString(digital));
		}
		return md5str.toString().toUpperCase();
	}

	/**
	 * 把字节数组转换成md5
	 *
	 * @param input
	 * @return
	 */
	public static byte[] bytesToMD5(byte[] input) {
		// String md5str = null;
		byte[] buff = null;
		try {
			// 创建一个提供信息摘要算法的对象，初始化为md5算法对象
			MessageDigest md = MessageDigest.getInstance("MD5");
			// 计算后获得字节数组
			buff = md.digest(input);
			// 把数组每一字节换成16进制连成md5字符串
			// md5str = bytesToHex(buff);
		} catch (Exception e) {
			log.error(e);
		}
		return buff;
	}

	/**
	 * 将字符串格式装换成DATE类型
	 *
	 * @param date
	 * @param type
	 *            被转换的字符串格式，如：yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static Date string2Date(String date, String type) {
		SimpleDateFormat sdf = new SimpleDateFormat(type);
		Date time = null;
		try {
			time = sdf.parse(date);
		} catch (ParseException e) {
			log.error("字符串格式装换成DATE类型出错", e);
		}
		return time;
	}

	/**
	 * 将DATE类型装换成字符串格式
	 *
	 * @param date
	 * @param type
	 *            要转换成的字符串格式，如：yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String date2String(Date date, String type) {
		SimpleDateFormat sdf = new SimpleDateFormat(type);
		String time = sdf.format(date);
		return time;
	}

	/**
	 * 根据长度转换成SQL设值串，如：?,?,?,?
	 *
	 * @param length
	 * @return
	 */
	public static String changeSqlValueByLen(int length) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < length; i++) {
			sb.append("?,");
		}
		if (sb.length() > 0) {
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	/**
	 * 验证字符串是否全是数字
	 *
	 * @param str
	 * @return
	 */
	public static boolean validateStrIsNum(String str) {
		for (int i = 0; i < str.length(); i++) {
			if (Character.isDigit(str.charAt(i))) {
				continue;
			} else {
				return false;
			}
		}
		return true;
	}

	/**
	 * 获取当前年和周
	 *
	 * @return 年份+周数，201414
	 */
	public static String getYearAndWeek() {
		Calendar cl = Calendar.getInstance();
		int week = cl.get(Calendar.WEEK_OF_YEAR);
		cl.add(Calendar.DAY_OF_MONTH, -7);
		int year = cl.get(Calendar.YEAR);
		if (week < cl.get(Calendar.WEEK_OF_YEAR)) {
			year += 1;
		}
		return (year + "") + (week + "");
	}

	/**
	 * 生成一个唯一的事务ID
	 *
	 * @return
	 */
	public synchronized static Long generateTransactionId() {
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			log.error("getTransactionId出错！", e);
		}
		return Long.parseLong(System.currentTimeMillis() + CommonConstant.PLATFORM_IDENTITY_CODE);
	}

	/**
	 * 生成一个唯一的订单id
	 *
	 * @return
	 */
	public synchronized static String generateOrderNumber() {
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			log.error(e);
		}
		Calendar curr = Calendar.getInstance();

		StringBuffer suffix = new StringBuffer(
				((curr.get(Calendar.HOUR_OF_DAY) * 60 * 60 * 1000) + (curr.get(Calendar.MINUTE) * 60 * 1000)
						+ (curr.get(Calendar.SECOND) * 1000) + curr.get(Calendar.MILLISECOND)) + "");
		int len = suffix.toString().length();
		if (len >= 0 && len < 8) {
			int size = 8 - len;
			for (int i = 0; i < size; i++)
				suffix.insert(0, "0");
		}
		return CommonUtil.date2String(curr.getTime(), "yyyyMMdd").substring(2) + suffix
				+ CommonConstant.PLATFORM_IDENTITY_CODE;
	}

	public static String getRemoteIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if (ip != null && ip.length() > 15) {
			if (ip.indexOf(",") > 0) {
				ip = ip.substring(0, ip.indexOf(","));
			}
		}
		return ip;
	}

	/**
	 * 是否微信brower
	 * 
	 * @param userAgent
	 * @return
	 */
	public static boolean isWeiXinBrower(String userAgent) {

		// log.info("userAgent is: " + userAgent);
		boolean flag = false;
		if (userAgent == null || userAgent.equals(""))
			return flag;
		userAgent = userAgent.toLowerCase();

		if (userAgent.contains("micromessenger")) {
			flag = true;
		}
		return flag;
	}

	public static boolean isWeiXinBrower(HttpServletRequest request) {
		String userAgent = request.getHeader("User-Agent");
		// log.info("userAgent is: " + userAgent);
		boolean flag = false;
		if (userAgent == null || userAgent.equals(""))
			return flag;
		userAgent = userAgent.toLowerCase();

		if (userAgent.contains("micromessenger")) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 判断微信的版本是否是>5.0版本以上
	 * 
	 * @param userAgent
	 * @return
	 */
	public static boolean isWeiXinVersionMoreThan5(String userAgent) {
		// String str =
		// "Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X)
		// AppleWebKit/534.46(KHTML,likeGeocko) Mobile/9B206
		// MicroMessenger/5.0"
		// ;
		// boolean bf1 = str.contains("MicroMessenger/") ;
		// log.info("userAgent is: " + userAgent);
		boolean flag = false;
		if (userAgent == null || userAgent.equals(""))
			return flag;
		userAgent = userAgent.toLowerCase();

		if (userAgent.contains("micromessenger")) {
			int len1 = userAgent.indexOf("micromessenger");
			String userAgent2 = userAgent.substring(len1, userAgent.length() - 1);
			String[] mm3 = userAgent2.split("/");
			if (mm3.length > 1) {
				String mm = mm3[1];
				mm = mm.substring(0, 3);
				float wxversion = Float.parseFloat(mm);
				if (wxversion >= 5.0f)
					flag = true;
			}
		}
		return flag;
	}

	public static void getWeiXinVersion(HttpServletRequest request, Map<String, Object> mv) {
		boolean flag = CommonUtil.isWeiXinVersionMoreThan5(request.getHeader("User-Agent"));
		mv.put("iswx5version", (flag ? "1" : "0")); // 1表示 >=5.0以上的版本
	}

	public static String readTxtFile(String filePath) {
		StringBuffer sb = new StringBuffer();
		File file = null;
		InputStreamReader read = null;
		BufferedReader bufferedReader = null;
		try {
			String encoding = "UTF-8";
			file = new File(filePath);
			if (file.isFile() && file.exists()) // 判断文件是否存在
			{
				read = new InputStreamReader(new FileInputStream(file), encoding); // 考虑到编码格式
				bufferedReader = new BufferedReader(read);
				String lineTxt = null;
				while ((lineTxt = bufferedReader.readLine()) != null) {
					sb.append(lineTxt + "\n");
				}

			} else {
				log.error("----readTxtFile---找不到指定的文件");

			}
		} catch (Exception e) {
			log.error("---readTxtFile----读取文件内容出错", e);
		} finally {
			try {
				bufferedReader.close();
				read.close();
			} catch (IOException e) {
				log.error("IOException", e);
			}
		}
		return sb.toString();
	}

	public static String getWxShareUrl(Map<String, String> reqParams) {
		String wxshareurlparams = "";
		if (reqParams == null || reqParams.isEmpty())
			return wxshareurlparams;
		String code = reqParams.get("code");
		String state = reqParams.get("state");
		String from = reqParams.get("from");
		String isappinstalled = reqParams.get("isappinstalled");

		if (code != null && !code.equals(""))
			wxshareurlparams += "code=" + code + "&";
		if (state != null && !state.equals(""))
			wxshareurlparams += "state=" + state + "&";
		if (from != null && !from.equals(""))
			wxshareurlparams += "from=" + from + "&";
		if (isappinstalled != null && !isappinstalled.equals(""))
			wxshareurlparams += "isappinstalled=" + isappinstalled + "&";

		if (wxshareurlparams != "")
			wxshareurlparams = wxshareurlparams.substring(0, wxshareurlparams.length() - 1);
		return wxshareurlparams;
	}
	
	public static String replaceIllegalEmoji(String content)
    {
        Pattern emoji = Pattern.compile("[\\x{10000}-\\x{10FFFF}]", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        Matcher mat = emoji.matcher(content);
        return mat.replaceAll("?");
    }
	
	public static byte[] convertHttpFile2Bytes(String httpFile)
        throws IOException
    {
        URL url = new URL(httpFile);
        URLConnection urlConn = url.openConnection();
        return convertInputStream2Bytes(urlConn.getInputStream());
    }
}
